package com.lambda.hybrid;

import android.app.Activity;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Build;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;

import com.lambda.hybrid.handler.GetCacheHandler;
import com.lambda.hybrid.handler.GetClipboardHandler;
import com.lambda.hybrid.handler.GetStorageHandler;
import com.lambda.hybrid.handler.HideHUDHandler;
import com.lambda.hybrid.handler.MakePhoneCallHandler;
import com.lambda.hybrid.handler.SaveImageToAlbumHandler;
import com.lambda.hybrid.handler.SetCacheHandler;
import com.lambda.hybrid.handler.SetClipboardHandler;
import com.lambda.hybrid.handler.SetConfigHandler;
import com.lambda.hybrid.handler.SetStorageHandler;
import com.lambda.hybrid.handler.ShowAlertHandler;
import com.lambda.hybrid.handler.ShowHUDHandler;
import com.lambda.hybrid.handler.TextHUDHandler;
import com.lambda.hybrid.utils.ACache;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;

import org.json.JSONException;

/**
 * Created by micr on 2017/12/28 0028.
 */
public abstract class HybridView extends WebView {
    private static final String TAG = "HybridView";

    private HybridClient mHybridClient;
    private boolean mIsDestroy;

    View statusBar;
    HybridToolbar toolbar;
    Paint mProgressPaint = new Paint();
    RectF mProgressRect = new RectF();

    HybridConfig hybridConfig;
    boolean progressFinish;

    private float mProgress;

    public HybridView(Context context) {
        this(context, null);
    }

    public HybridView(Context context, AttributeSet attributeSet) {
        this(context, attributeSet, 0);
    }

    public HybridView(Context context, AttributeSet attributeSet, int i) {
        super(context, attributeSet, i);
        setVerticalScrollBarEnabled(false);
        setHorizontalScrollBarEnabled(false);

        WebSettings settings = getSettings();
        {
            settings.setJavaScriptEnabled(true);

            settings.setDomStorageEnabled(true);
            settings.setAllowFileAccess(false);

            settings.setAllowFileAccessFromFileURLs(false);
            settings.setAllowUniversalAccessFromFileURLs(false);

            settings.setDatabaseEnabled(true);
            settings.setLoadsImagesAutomatically(true);
            // 可任意比例缩放
            settings.setUseWideViewPort(true);
            // setUseWideViewPort方法设置webview推荐使用的窗口。
            // setLoadWithOverviewMode方法是设置webview加载的页面的模式。
            settings.setLoadWithOverviewMode(true);
            settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
            settings.setAppCacheEnabled(true);
            settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
            settings.setAppCachePath(context.getCacheDir().getAbsolutePath() + "/webkit");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                settings.setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
            }
        }

        hybridConfig = new HybridConfig(this);

        mHybridClient = generateWebViewClient();
        setWebViewClient(mHybridClient);
        setWebChromeClient(generateWebChromeClient());

        setBackgroundColor(Color.TRANSPARENT);

        registerHandler();
    }

    @Override
    public void destroy() {
        if (mIsDestroy) return;

        mIsDestroy = true;
        setWebViewClient(null);
        setWebChromeClient(null);
        loadUrl("about:blank");
        super.destroy();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mProgressRect.bottom = Math.max(hybridConfig.getProgressHeight(), mProgressRect.height());
    }

    public void registerHandler() {
        Context context = getContext();

        mHybridClient.register("showHUD", new ShowHUDHandler(this));
        mHybridClient.register("hideHUD", new HideHUDHandler(this));
        mHybridClient.register("showTextHud", new TextHUDHandler(this));

        SharedPreferences storage = context.getSharedPreferences("hybrid_storage", Context.MODE_PRIVATE);
        mHybridClient.register("setStorage", new SetStorageHandler(storage));
        mHybridClient.register("getStorage", new GetStorageHandler(storage));

        ACache cache = ACache.get(context, "hybrid_cache");
        mHybridClient.register("setCache", new SetCacheHandler(cache));
        mHybridClient.register("getCache", new GetCacheHandler(cache));

        ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
        mHybridClient.register("setClipboard", new SetClipboardHandler(clipboardManager));
        mHybridClient.register("getClipboard", new GetClipboardHandler(clipboardManager));

        mHybridClient.register("makePhoneCall", new MakePhoneCallHandler(context));
        mHybridClient.register("saveImageToAlbum", new SaveImageToAlbumHandler(context));
        mHybridClient.register("showAlert", new ShowAlertHandler(context));

        mHybridClient.register("setViewConfig", new SetConfigHandler(this));
    }

    public void invoke(String name, String data, Callback callback) {
        mHybridClient.invoke(name, data, callback);
    }

    public void setProgress(float progress) {
        mProgress = progress;
        mProgressRect.right = progress * getMeasuredWidth();
        ViewCompat.postInvalidateOnAnimation(this);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if (mProgress < 1.0f && mProgress > 0.0f) {
            mProgressPaint.setColor(hybridConfig.getProgressColor());
            canvas.drawRect(mProgressRect, mProgressPaint);
        }
    }

    public void setToolbar(View view) {
        toolbar = new HybridToolbar(this, view);
    }

    public void setStatusBar(View view) {
        statusBar = view;
    }

    protected HybridClient generateWebViewClient() {
        return new HybridClient(this);
    }

    protected HybridChromeClient generateWebChromeClient() {
        return new HybridChromeClient(this);
    }

    public void setConfig(String data) throws JSONException {
        hybridConfig.update(data);
    }

    public void onClose() {
        Context context = getContext();
        if (context instanceof Activity) {
            ((Activity) context).finish();
        }
    }
}
